home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / beos / PPBeDevKit.ZIP / PLAYERPR.TAR / PlayerPRO / Source / Import-Export / AMF.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-26  |  11.6 KB  |  471 lines

  1. /********************                        ***********************/
  2. //
  3. //    Player PRO 5.0 - DRIVER SOURCE CODE -
  4. //
  5. //    Library Version 5.0
  6. //
  7. //    To use with MAD Library for Mac: Symantec, CodeWarrior and MPW
  8. //
  9. //    Antoine ROSSET
  10. //    16 Tranchees
  11. //    1206 GENEVA
  12. //    SWITZERLAND
  13. //
  14. //    COPYRIGHT ANTOINE ROSSET 1996, 1997, 1998
  15. //
  16. //    Thank you for your interest in PlayerPRO !
  17. //
  18. //    FAX:                (+41 22) 346 11 97
  19. //    PHONE:             (+41 79) 203 74 62
  20. //    Internet:     RossetAntoine@bluewin.ch
  21. //
  22. /********************                        ***********************/
  23.  
  24. #include "MAD.h"
  25. #include "AMF.h"
  26. #include "RDriver.h"
  27.  
  28. #if defined(powerc) || defined(__powerc)
  29. enum {
  30.         PlayerPROPlug = kCStackBased
  31.         | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
  32.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
  33.         | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr)))
  34.         | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADMusic*)))
  35.         | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
  36.         | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( MADDriverSettings*)))
  37. };
  38.  
  39. ProcInfoType __procinfo = PlayerPROPlug;
  40. #else
  41. #include <A4Stuff.h>
  42. #endif
  43.  
  44. static Ptr            theAMFRead;
  45.  
  46. #define READAMFFILE(dst, size)    {BlockMove( theAMFRead, dst, size);    theAMFRead += (long) size;}
  47.  
  48.  
  49. Ptr MADPlugNewPtr( long size, MADDriverSettings* init)
  50. {
  51.     if( init->sysMemory) return NewPtrSys( size);
  52.     else return NewPtr( size);
  53. }
  54.  
  55. Ptr MADPlugNewPtrClear( long size, MADDriverSettings* init)
  56. {
  57.     if( init->sysMemory) return NewPtrSysClear( size);
  58.     else return NewPtrClear( size);
  59. }
  60.  
  61. Cmd* GetMADCommand( register short PosX, register short    TrackIdX, register PatData*    tempMusicPat)
  62. {
  63.     if( PosX < 0) PosX = 0;
  64.     else if( PosX >= tempMusicPat->header.size) PosX = tempMusicPat->header.size -1;
  65.         
  66.     return( & (tempMusicPat->Cmds[ (tempMusicPat->header.size * TrackIdX) + PosX]));
  67. }
  68.  
  69. void pStrcpy(register unsigned char *s1, register unsigned char *s2)
  70. {
  71.     register short len, i;
  72.     
  73.     len = *s2;
  74.     for ( i = 0; i <= len; i++) s1[ i] = s2[ i];
  75. }
  76.  
  77. short Tdecode16( void *msg_buf)
  78. {
  79.   unsigned char *buf = msg_buf;
  80.   
  81.   return ( (short) buf[1] << 8) | ( (short) buf[0]);
  82. }
  83.  
  84. unsigned long Tdecode32( void *msg_buf)
  85. {
  86.   unsigned char *buf = msg_buf;
  87.   
  88.   return( (unsigned long) buf[3] << 24) | ( (unsigned long) buf[2] << 16) | ( (unsigned long) buf[ 1] << 8) | ( (unsigned long) buf[0]);
  89. }
  90.  
  91. OSErr AMF2Mad( Ptr AMFCopyPtr, long size, MADMusic *theMAD, MADDriverSettings *init)
  92. {
  93. Byte                    tempByte;
  94. short                     i, x, noIns, tempShort, trackCount, trckPtr, t;
  95. long                     inOutCount, OffSetToSample = 0L, z;
  96. OSErr                    theErr = noErr;
  97. Ptr                        tempPtr;
  98. OSType                    AMFType;
  99. long                     finetune[16] = 
  100.                         {
  101.                             8363,    8413,    8463,    8529,    8581,    8651,    8723,    8757,
  102.                             7895,    7941,    7985,    8046,    8107,    8169,    8232,    8280
  103.                         };
  104.  
  105. short                    pan, uusize, oldIns = 1;
  106.  
  107. theAMFRead = AMFCopyPtr;
  108.  
  109. READAMFFILE( &AMFType, 4);        // AMF Type
  110. if( AMFType >= 0x414D460C ) pan = 32;
  111. else pan = 16;
  112.  
  113. if( AMFType == 0x414D4601 ) uusize = 3;
  114. else if( AMFType >= 0x414D460A ) oldIns = 0;
  115. else if( AMFType!= 0x414D4608 && AMFType != 0x414D4609) return MADFileNotSupportedByThisPlug;
  116.  
  117. // Conversion
  118. theMAD->header = (MADSpec*) MADPlugNewPtrClear( sizeof( MADSpec), init);    
  119. if( theMAD->header == 0L) return MADNeedMemory;
  120.  
  121. mystrcpy( theMAD->header->infos, (Ptr) "\pConverted by PlayerPRO AMF Plug (⌐Antoine ROSSET <rossetantoine@bluewin.ch>)");
  122.  
  123. theMAD->header->MAD = 'MADI';
  124.  
  125. READAMFFILE( theMAD->header->name, 32);
  126. READAMFFILE( &tempByte, 1);        noIns = tempByte;
  127. READAMFFILE( &tempByte, 1);        theMAD->header->numPat = tempByte;
  128. READAMFFILE( &tempShort, 2);    trackCount = Tdecode16( &tempShort);
  129.  
  130. if( AMFType >= 0x414D4609 )
  131. {
  132.     READAMFFILE( &tempByte, 1);        theMAD->header->numChn = tempByte;
  133.     
  134.     READAMFFILE( &tempByte, pan);
  135.     if( AMFType < 0x414D460B )
  136.     {
  137.         //memcpy(&module->channelPanning,order16,16);
  138.     }
  139. }
  140. else theMAD->header->numChn = 4;
  141. if( AMFType >= 0x414D460D )
  142. {
  143.     READAMFFILE( &tempByte, 1);        theMAD->header->tempo = tempByte;
  144.     READAMFFILE( &tempByte, 1);        theMAD->header->speed = tempByte;
  145. }
  146. else
  147. {
  148.     theMAD->header->speed            = 6;
  149.     theMAD->header->tempo            = 125;
  150. }
  151.  
  152. //theMAD->header->numPointers        = oldMAD->numPointers;
  153. //BlockMove( oldMAD->oPointers, theMAD->header->oPointers, 128);
  154.  
  155. /**** Patterns *******/
  156.  
  157. for( i = 0; i < theMAD->header->numPat; i++ )
  158. {
  159.     long patSize;
  160.     
  161.     if( AMFType >= 0x414D460E )
  162.     {
  163.         READAMFFILE( &tempShort, 2);    patSize = Tdecode16( &tempShort);
  164.     }
  165.     else patSize = 64;
  166.  
  167.     theMAD->partition[ i] = (PatData*) MADPlugNewPtrClear( sizeof( PatHeader) + theMAD->header->numChn * patSize * sizeof( Cmd), init);
  168.     if( theMAD->partition[ i] == 0L) return MADNeedMemory;
  169.     
  170.     theMAD->partition[ i]->header.size         = patSize;
  171.     theMAD->partition[ i]->header.compMode     = 'NONE';
  172.     
  173.     for( x = 0; x < 20; x++) theMAD->partition[ i]->header.name[ x] = 0;
  174.     
  175.     theMAD->partition[ i]->header.patBytes = 0L;        theMAD->partition[ i]->header.unused2 = 0L;
  176.     
  177.     for( x = 0; x < theMAD->header->numChn; x++ )
  178.     {
  179.     //    fread(&(module->patterns[t].track[i]),2,1,file);
  180.         READAMFFILE( &tempShort, 2);
  181.     }
  182. }
  183. for( i = theMAD->header->numPat; i < MAXPATTERN ; i++) theMAD->partition[ i] = 0L;
  184.  
  185. for( i = 0; i < MAXTRACK; i++)
  186. {
  187.     if( i % 2 == 0) theMAD->header->chanPan[ i] = MAX_PANNING/4;
  188.     else theMAD->header->chanPan[ i] = MAX_PANNING - MAX_PANNING/4;
  189.     
  190.     theMAD->header->chanVol[ i] = MAX_VOLUME;
  191. }
  192.  
  193.     theMAD->header->generalVol        = 64;
  194.     theMAD->header->generalSpeed    = 80;
  195.     theMAD->header->generalPitch    = 80;
  196.  
  197.  
  198. /**** Instruments header *****/
  199.  
  200. theMAD->fid = ( InstrData*) MADPlugNewPtrClear( sizeof( InstrData) * (long) MAXINSTRU, init);
  201. if( !theMAD->fid) return MADNeedMemory;
  202.  
  203. theMAD->sample = ( sData**) MADPlugNewPtrClear( sizeof( sData*) * (long) MAXINSTRU * (long) MAXSAMPLE, init);
  204. if( !theMAD->sample) return MADNeedMemory;
  205.  
  206. for( i = 0; i < MAXINSTRU; i++) theMAD->fid[ i].firstSample = i * MAXSAMPLE;
  207.  
  208. for( i = 0; i < noIns; i++)
  209. {
  210.     InstrData        *curIns = &theMAD->fid[ i];
  211.     
  212.     if( oldIns )
  213.     {
  214.         OLDINSTRUMENT    oi;
  215.         
  216.         READAMFFILE( &oi, sizeof( OLDINSTRUMENT));
  217.         
  218.         
  219.         BlockMove( oi.name, curIns->name, 32);
  220.         curIns->type = 0;
  221.         
  222.         if( oi.size > 0)
  223.         {
  224.             sData    *curData;
  225.             
  226.             curIns->numSamples = 1;
  227.             
  228.             curData = theMAD->sample[ i*MAXSAMPLE + 0] = (sData*) MADPlugNewPtrClear( sizeof( sData), init);
  229.             
  230.             curData->size        = Tdecode32( &oi.size);
  231.             curData->loopBeg     = oi.loopstart;
  232.             curData->loopSize     = oi.loopend - oi.loopstart;
  233.             if( oi.loopend == 65535)
  234.             {
  235.                 curData->loopSize = curData->loopBeg = 0;
  236.             }
  237.             curData->vol        = oi.volume;
  238.             curData->c2spd        = oi.rate;    //finetune[ oldMAD->fid[ i].fineTune];
  239.             curData->loopType    = 0;
  240.             curData->amp        = 8;
  241.             
  242.             curData->relNote    = 0;
  243.             
  244.             curData->data         = MADPlugNewPtr( curData->size, init);
  245.             if( curData->data == 0L) return MADNeedMemory;
  246.         }
  247.         else curIns->numSamples = 0;
  248.     }
  249.     else
  250.     {
  251.         INSTRUMENT        oi;
  252.         
  253.         READAMFFILE( &oi, sizeof( INSTRUMENT));
  254.         theAMFRead--;
  255.         
  256.         BlockMove( oi.name, curIns->name, 32);
  257.         curIns->type = 0;
  258.         
  259.         if( oi.size > 0)
  260.         {
  261.             sData    *curData;
  262.             
  263.             curIns->numSamples = 1;
  264.             
  265.             curData = theMAD->sample[ i*MAXSAMPLE + 0] = (sData*) MADPlugNewPtrClear( sizeof( sData), init);
  266.             
  267.             curData->size        = Tdecode32( &oi.size);
  268.             curData->loopBeg     = Tdecode32( &oi.loopstart);
  269.             curData->loopSize     = Tdecode32( &oi.loopend) - Tdecode32( &oi.loopstart);
  270.             if( oi.loopend == 65535)
  271.             {
  272.                 curData->loopSize = curData->loopBeg = 0;
  273.             }
  274.             curData->vol        = oi.volume;
  275.             curData->c2spd        = NOFINETUNE;    //oi.rate;    //finetune[ oldMAD->fid[ i].fineTune];
  276.             curData->loopType    = 0;
  277.             curData->amp        = 8;
  278.             
  279.             curData->relNote    = 0;
  280.             
  281.             curData->data         = MADPlugNewPtr( curData->size, init);
  282.             if( curData->data == 0L) return MADNeedMemory;
  283.         }
  284.         else curIns->numSamples = 0;
  285.     }
  286. }
  287.  
  288. trckPtr = 0;
  289. for( t = 0; t < trackCount; t++ )
  290. {
  291.     READAMFFILE( &tempShort, 2);    tempShort = Tdecode16( &tempShort);
  292.     if( tempShort > trckPtr) trckPtr = tempShort;
  293. }
  294.  
  295. for( t = 0; t < trckPtr; t++)
  296. {
  297.     READAMFFILE( &tempShort, 2);        tempShort = Tdecode16( &tempShort);
  298.     READAMFFILE( &tempByte, 1);
  299.     
  300.     if( tempShort == 0 ) t=t;
  301.     else
  302.     {
  303.         Ptr tPtr = NewPtr( tempShort * 3 + size);
  304.         READAMFFILE( tPtr,tempShort * 3 + size);
  305.         DisposePtr( tPtr);
  306.     }
  307. }
  308.  
  309. for( i = 0; i < noIns; i++)
  310. {
  311.     InstrData        *curIns = &theMAD->fid[ i];
  312.     
  313.     if( curIns->numSamples > 0)
  314.     {
  315.         sData    *curData;
  316.         
  317.         curData = theMAD->sample[ i*MAXSAMPLE + 0];
  318.         
  319.         READAMFFILE( curData->data, curData->size);
  320.     }
  321. }
  322.  
  323. return noErr;
  324. }
  325.  
  326. OSErr TestAMFFile( Ptr AlienFile)
  327. {
  328.     unsigned long    *myMADSign = (unsigned long*) AlienFile;
  329.     
  330.     if( (*myMADSign & 0xFFFFFF00) == 0x414D4600) return noErr;
  331.     else return MADFileNotSupportedByThisPlug;
  332.     
  333.     return noErr;
  334. }
  335.  
  336. OSErr ExtractAMFInfo( PPInfoRec *info, Ptr AlienFile)
  337. {
  338.     long        PatternSize;
  339.     short        i;
  340.     short        tracksNo;
  341.     
  342.     /*** Signature ***/
  343.     
  344.     info->signature = 'AMF ';
  345.     
  346.     /*** Internal name ***/
  347.     
  348.     info->internalFileName[ 31] = '\0';
  349.  
  350.     /*** Tracks ***/
  351.     
  352.     info->totalTracks = 0;
  353.         
  354.     /*** Total Patterns ***/
  355.     
  356.     info->totalPatterns = 0;
  357.     
  358.     /*** Partition Length ***/
  359.     
  360.     info->partitionLength = 0;
  361.     
  362.     /*** Total Instruments ***/
  363.     info->totalInstruments = 0;
  364.     
  365.     pStrcpy( (unsigned char*) info->formatDescription, "\pAMF Plug");
  366.  
  367.     return noErr;
  368. }
  369.  
  370. /*****************/
  371. /* MAIN FUNCTION */
  372. /*****************/
  373.  
  374. OSErr main( OSType order, char *AlienFileFSSpec, MADMusic *MadFile, PPInfoRec *info, MADDriverSettings *init)
  375. {
  376.     OSErr    myErr;
  377.     Ptr        AlienFile;
  378.     short    iFileRefI;
  379.     long    sndSize;
  380.     
  381. #ifndef powerc
  382.     long    oldA4 = SetCurrentA4();             //this call is necessary for strings in 68k code resources
  383. #endif
  384.     
  385.     myErr = noErr;
  386.  
  387.     switch( order)
  388.     {
  389.         case 'IMPL':
  390.             myErr = FSpOpenDF( AlienFileFSSpec, fsCurPerm, &iFileRefI);
  391.             if( myErr == noErr)
  392.             {
  393.                 GetEOF( iFileRefI, &sndSize);
  394.             
  395.                 // ** MEMORY Test Start
  396.                 AlienFile = MADPlugNewPtr( sndSize * 2L, init);
  397.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  398.                 // ** MEMORY Test End
  399.                 
  400.                 else
  401.                 {
  402.                     DisposePtr( AlienFile);
  403.                     
  404.                     AlienFile = MADPlugNewPtr( sndSize, init);
  405.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  406.                     if( myErr == noErr)
  407.                     {
  408.                         myErr = TestAMFFile( AlienFile);
  409.                         if( myErr == noErr)
  410.                         {
  411.                             myErr = AMF2Mad( AlienFile, GetPtrSize( AlienFile), MadFile, init);
  412.                         }
  413.                     }
  414.                     DisposePtr( AlienFile);    AlienFile = 0L;
  415.                 }
  416.                 FSClose( iFileRefI);
  417.             }
  418.         break;
  419.         
  420.         case 'TEST':
  421.             myErr = FSpOpenDF( AlienFileFSSpec, fsCurPerm, &iFileRefI);
  422.             if( myErr == noErr)
  423.             {
  424.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  425.                 
  426.                 AlienFile = MADPlugNewPtr( sndSize, init);
  427.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  428.                 else
  429.                 {
  430.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  431.                     myErr = TestAMFFile( AlienFile);
  432.                     
  433.                     DisposePtr( AlienFile);    AlienFile = 0L;
  434.                 }
  435.                 FSClose( iFileRefI);
  436.             }
  437.         break;
  438.  
  439.         case 'INFO':
  440.             myErr = FSpOpenDF( AlienFileFSSpec, fsCurPerm, &iFileRefI);
  441.             if( myErr == noErr)
  442.             {
  443.                 GetEOF( iFileRefI, &info->fileSize);
  444.             
  445.                 sndSize = 5000L;    // Read only 5000 first bytes for optimisation
  446.                 
  447.                 AlienFile = MADPlugNewPtr( sndSize, init);
  448.                 if( AlienFile == 0L) myErr = MADNeedMemory;
  449.                 else
  450.                 {
  451.                     myErr = FSRead( iFileRefI, &sndSize, AlienFile);
  452.                     if( myErr == noErr)
  453.                     {
  454.                         myErr = ExtractAMFInfo( info, AlienFile);
  455.                     }
  456.                     DisposePtr( AlienFile);    AlienFile = 0L;
  457.                 }
  458.                 FSClose( iFileRefI);
  459.             }
  460.         break;
  461.         
  462.         default:
  463.             myErr = MADOrderNotImplemented;
  464.         break;
  465.     }
  466.  
  467.     #ifndef powerc
  468.         SetA4( oldA4);
  469.     #endif
  470.     return myErr;
  471. }